#ifndef SYMMETRYBOUNDARY_H
#define SYMMETRYBOUNDARY_H

#include <vector>
#include <complex>
#include <string>
#include <memory>
#include <iostream>

// 包含Vector_3D头文件
#include "Vector_3D.h"
class Vector_3D;

// Forward declaration to avoid circular dependency
namespace FieldCircuitCoupling {
    typedef std::complex<double> Complex;
    class FieldSolverInterface;
}

namespace SymmetryBoundary {

// Symmetry boundary types
enum class SymmetryType {
    NONE,           // No symmetry
    SYMMETRIC,      // Electric field symmetry (even)
    ANTISYMMETRIC,  // Electric field antisymmetry (odd)
    PEC,            // Perfect Electric Conductor
    PMC,            // Perfect Magnetic Conductor
    ASYMMETRIC_EXCITATION  // Asymmetric excitation
};

// Plane orientation for symmetry boundary
enum class PlaneOrientation {
    XY_PLANE,       // z = 0 plane
    YZ_PLANE,       // x = 0 plane
    XZ_PLANE        // y = 0 plane
};

// Symmetry boundary configuration
struct SymmetryConfig {
    PlaneOrientation plane;          // Plane orientation
    SymmetryType type;               // Symmetry type
    double planeOffset;              // Plane offset from origin
    bool enabled;                    // Enable/disable this symmetry plane
};

// Symmetry boundary manager class
class SymmetryBoundaryManager {
public:
    SymmetryBoundaryManager();
    ~SymmetryBoundaryManager();
    
    // Set symmetry configuration for a specific plane
    void setSymmetryConfig(const SymmetryConfig& config);
    
    // Get symmetry configuration for a specific plane
    bool getSymmetryConfig(PlaneOrientation plane, SymmetryConfig& config) const;
    
    // Apply symmetry to the impedance matrix
    bool applySymmetryToImpedanceMatrix(
        std::vector<std::vector<FieldCircuitCoupling::Complex>>& impedanceMatrix,
        const std::vector<Vector_3D>& basisFunctionPositions) const;
    
    // Apply symmetry to the excitation vector
    bool applySymmetryToExcitation(
        std::vector<FieldCircuitCoupling::Complex>& excitation,
        const std::vector<Vector_3D>& basisFunctionPositions) const;
    
    // Apply symmetry to the solution vector (expand to full problem size)
    bool expandSolution(
        std::vector<FieldCircuitCoupling::Complex>& solution,
        const std::vector<Vector_3D>& basisFunctionPositions) const;
    
    // Compute the image position of a point with respect to a symmetry plane
    Vector_3D computeImagePosition(
        const Vector_3D& point, 
        const SymmetryConfig& config) const;
    
    // Check if symmetry is enabled for any plane
    bool isAnySymmetryEnabled() const;
    
    // Get the transformation factor for a symmetry type
    FieldCircuitCoupling::Complex getSymmetryFactor(
        SymmetryType type,
        const Vector_3D& vector) const;
    
    // Initialize with field solver
    bool initialize(std::shared_ptr<FieldCircuitCoupling::FieldSolverInterface> fieldSolver);
    
    // Get reduced problem size factor (how many times the problem is reduced)
    int getReductionFactor() const;
    
    // Generate basis function position map for symmetry expansion
    bool generatePositionMap(
        const std::vector<Vector_3D>& originalPositions,
        std::vector<std::pair<size_t, size_t>>& positionMap) const;
    
private:
    std::vector<SymmetryConfig> symmetryPlanes;  // Symmetry configurations for all planes
    std::shared_ptr<FieldCircuitCoupling::FieldSolverInterface> fieldSolver;  // Reference to field solver
    
    // Internal methods
    bool isPointOnSymmetryPlane(
        const Vector_3D& point, 
        const SymmetryConfig& config) const;
    
    double getPlaneCoordinate(
        const Vector_3D& point, 
        PlaneOrientation plane) const;
    
    Vector_3D setPlaneCoordinate(
        const Vector_3D& point, 
        PlaneOrientation plane, 
        double value) const;
    
    // Apply symmetry to a single plane
    bool applySinglePlaneSymmetry(
        std::vector<std::vector<FieldCircuitCoupling::Complex>>& impedanceMatrix,
        const std::vector<Vector_3D>& basisFunctionPositions,
        const SymmetryConfig& config) const;
};

// Factory function to create symmetry boundary manager
__declspec(dllexport) std::shared_ptr<SymmetryBoundaryManager> createSymmetryBoundaryManager();

// Utility functions
extern SymmetryType stringToSymmetryType(const std::string& typeStr);
extern std::string symmetryTypeToString(SymmetryType type);
extern PlaneOrientation stringToPlaneOrientation(const std::string& planeStr);
extern std::string planeOrientationToString(PlaneOrientation plane);

} // namespace SymmetryBoundary

#endif // SYMMETRYBOUNDARY_H